/** @description 命名空间注册 */
Ccay.Core.Namespace = {
	/**
	 * @description 命名空间注册，如果已经已经存在，则返回该对象，否则新建并换回该命名空间对象
	 * @param namespace
	 *            {string}
	 * @return object {Object}
	 */
	register : function(namespace) {
		var root = window;
		var objs = namespace.split('.');
		var len = objs.length;
		for (var i = 0; i < len; i++) {
			root = root[objs[i]] = root[objs[i]] || {};
		}
		return root;
	}, 
	
	regModule : function (namespace,obj){
		var root = window;
		var objs = namespace.split('.');
		var len = objs.length;
		for (var i = 0; i < len; i++) {
			root = root[objs[i]] = root[objs[i]] || obj || {};
		}
		Ccay.Module.modules.put(namespace);
		return root;
	},
	/**
	 * @description 找到名为name的对象，找到了便返回，否则返回false
	 * @param name
	 *            {string} js变量的全名，如“Ccay.Demo.variable1”
	 * @return object {Object}
	 */
	getVariable : function(name) {
		var value = false;
		try {
			value = eval(name) || false;
		} catch (e) {
		}
		return value;
	},
	/**
	 * @description 根据name找到命名空间
	 * @param name
	 *            {string} 命名空间字串
	 * @return object {Object} 命名空间对象
	 */
	get : function(name) {
		if (name) {
			name = name.split('.');
			if (name.length) {
				var ns = window;
				for (var i = 0; ns && name[i]; i++)
					ns = ns[name[i]];
				return ns;
			}
		}
		return null;
	}
};

/**
 * 不支持时构造console对象
 */
if(!window.console){
	window.console = {
		log : function(){} ,
		debug: function(){},
		warn:function(){},
		info:function(){},
		error:function(){}
	}
};
/**
 * 日志API，通过level调整级别
 * 
 * @type Objext
 */
Ccay.Log = {

	level : workspaceVO.config.ScriptLogLevel? parseInt(workspaceVO.config.ScriptLogLevel) : 2 ,
	
	debug: function(msg){
		if(this.level == 1){
			 window.console.log(msg);
		}
	},
	
	info: function(msg){
		if(this.level <= 2){
			window.console.info(msg);
		}
	},
	
	warn: function(msg){
		if(this.level <= 3){
			window.console.error("warn:" + msg);
		}
	},
	
	error: function(msg){
		if(this.level <= 4){
			window.console.error(msg);
		}
	}
};

/**
 * @description ccay 前台脚本日志输出接口
 * @param msg
 *            {String} 日志信息
 * @param level
 *            {number}
 *            log模式,有四个常量可选Ccay.Config.Log.debug、Ccay.Config.Log.info、Ccay.Core.log.LOG_WARN、Ccay.Core.log.LOG_ERROR
 */
Ccay.Core.log = function(msg, level) {
	// 不传递level，默认为info日志
	/* level=level || Ccay.Config.Log.debug; */
	// 控制输出日志的模式
	if(!level){
		level = 2;
	}
	if(level >= Ccay.Log.level){
		window.console.log(msg);	 
	}
};


/**
 * _diffServerTime
 * 
 * @type {number} 页面加载后，读取服务器时间，并计算出服务器时间与本地时间之间的差异
 */

if (typeof(workspaceVO) === 'undefined') {	
	document.write("<h2>System error occured(Can not init workspace).</h2>");
	$("#firstLoading").remove();
}

Ccay.Core._diffServerTime = Ccay.Format.toDate(workspaceVO.serverTime)
		.getTime()
		- new Date().getTime();

/**
 * 得到服务器时间
 * 
 * @return serverTime
 */
Ccay.Core.getServerTime = function() {
	return new Date(new Date().getTime() + Ccay.Core._diffServerTime);
}

/** ----------------------------- Ccay.Module -------------------------------- */
/**
 * @description 模块对象
 * @param name
 *            {String} 模块名称
 */
Ccay.Module = function(name) {
	this.name = name;
	this.hasInit = false;
}

Ccay.Module.SupperClass = {}; // 模块对象的父类，用于扩展
Ccay.Module.modules = new Ccay.HashMap(); // 全局模块加载集合，保存已经加载过的模块名、与其初始化状态

/**
 * @description Ccay 前端模块定义函数， 基于AMD规范定义
 * @param moduleName
 *            {String} 模块名称
 * @param defineFunction
 *            {Function} 模块定义函数
 */
Ccay.Module.define = function(moduleName, defineFunction) {
	var module = Ccay.Core.Namespace.register(moduleName);
	$.extend(module, Ccay.Module.SupperClass);
	// 模块选择器初始化，如果模块有上下文，则通过该上下文查找元素，否则通过ContentPanel为context
	var selector = function(elmt, panel) {
		return (module.context || $(document)).find(elmt, panel);
	};
	// 调用模块定义，将模块对象对象注入定义方法中
	if(typeof defineFunction == "function"){
		defineFunction(module, selector); 
	}
	// 将定义的模块保存到map中
	Ccay.Module.modules.put(moduleName, new Ccay.Module(moduleName));
	Ccay.Core.log("加载模块：" + moduleName, Ccay.Config.Log.info);

}

/**
 * @description 初始化执行未初始化的模块的ready方法
 */
Ccay.Module.executeReady = function() {
	Ccay.Module.modules.each(function(moduleName, module) {
				var realModuleObj = Ccay.Core.Namespace.register(moduleName);
				if (!module.hasInit
						&& typeof(realModuleObj.ready) === "function") {
					realModuleObj.ready();
					module.hasInit = true;
				}
			});
}
/**
 * @description 根据模块名称，移除模块
 * @param moduleName
 *            {String} 模块名
 */
Ccay.Module.remove = function(moduleName) {
	if (moduleName) {
		try {
			var realModuleObj = Ccay.Core.Namespace.register(moduleName);
			if (realModuleObj && typeof(realModuleObj.exit) === "function") {
				Ccay.Core.log(moduleName + "模块定义了Exit方法，现在执行",
						Ccay.Config.Log.info);
				// 调用exit方法清理必要的资源
				realModuleObj.exit();
			}
			Ccay.Module.modules.remove(moduleName);

			eval(moduleName + "=null");
			
			Ccay.Core.log(moduleName + "模块数据清空", Ccay.Config.Log.info);
			
		} catch (e) {
			Ccay.Core.log(moduleName + "模块不存在，不需要注销", Ccay.Config.Log.info);
		};
		
	}
};

/**
 * @description 清除所有模块
 */
Ccay.Module.clear = function() {
	var keys = $.extend([], Ccay.Module.modules.keys);
	$.each(keys, function() {
				Ccay.Module.remove(this);
			});
};

/** ----------------------------- Ccay.Resource -------------------------------- */
Ccay.Resource = {
	/**
	 * @description 通过 HTTP GET 请求从服务器载入并执行一个 JavaScript 文件或CSS文件
	 * @param {string}
	 *            url
	 */
	register : function(url) {
		var reg = /\.css$/i;
		if (!reg.test(url)) {
			document.write('<script type="text/javascript" src="' + url
					+ '"  charset="utf-8"><\/script>');
		} else {
			document.write('<link  rel="stylesheet" href="' + url
					+ '" type="text/css">');
		}
	}
};

/** ----------------------------- Ccay.Page -------------------------------- */
/**
 * @description 外部接口，用于注册页面资源（传递两参数），或得到资源实际路径（只传递reskey）
 * @param pkey
 *            {String} 注册资源key
 * @param path
 *            {String} 资源相对路径，如省略该参数，则该方法为取资源路径
 * @return path {String} 仅当传递一个参数的时候，才有返回值。
 */
Ccay.Page = {
	ajaxCompleted : function(){
		return  Ccay.Core_ajaxCount.other < 1 && Ccay.Core_ajaxCount.get < 1;
	},
	register : function(pkey, path) {
		if (path)
			Ccay.Page._list[pkey] = path;
		else
			return Ccay.Page._list[pkey] || pkey;
	},
	has : function(key) {
		return Ccay.Page._list[key] ? true : false;
	},
	_list : {},
	/**
	 * @description 返回装载div
	 * @return {Object} 返回载入页面的div（jquery dom元素） 。
	 */
	getContentPanel : function() {
		return $("#" + Ccay.Config.Panel.main);
	},
	/**
	 * @description load方式载入页面资源，模拟跳转。如果url为空，则清空当前面板内容。（当浏览器
	 *              history退回到原点的时候，url则为空）
	 * @param url{String}
	 *            资源key值或实际路径
	 */
	_clearCache : true,
	_forwardCount : 0,
	_forward : function(url) {
		var panel = Ccay.Page.getContentPanel();
		// 无请求跳转url时，一般选中“首页”节点，无首页url事清空内容区 modify by l0095395 2013.10.18
		if (Ccay.DataHelper.isEmpty(url)) {
			Ccay.UI.loading();
			Ccay.Module.clear();
			Ccay.Page.clearCache();
			// 首页配置了url时，否则清空
			if(workspaceVO.leftMenuNode.url){
				panel.removeAttr('module').ccayLoad(workspaceVO.leftMenuNode.url.split("#!")[1]);
			}else{
				panel.removeAttr('module').empty();
			}
			Ccay.UI.loadingClose();
			Ccay.Layout.selectMenuByUrl();
			return;
		}
		// 如果达到访问模块的上限，并且当前页面没有与下一个页面有直接参数关联，则刷新整个页面
		with (Ccay.Page) {
			var refresTimes = Ccay.Config.Global.refresh;
			if (refresTimes && ++_forwardCount > refresTimes && _clearCache) {
				refresh();
			}
		}
		
		url=url.replaceAll(" ","%20")
		var Target = Ccay.Layout.Config.LeftMenu.Target, target = Ccay.Page
				.getRequest()["__target"];
		// 下面if语句中的代码处理非默认方式代开连接方式
		if (target && target != Target.self) {
			if (target == Target.frame) {
				var frame = $("<iframe id='#ccayContentframe'  src=" + url
						+ " frameborder=no border=0 ></iframe>").css({
							width : "100%",
							height : "800px"
						})
				Ccay.Page.getContentPanel().empty().append(frame);
				$("#ccayContentPanel").css("visibility", "inherit");
				Ccay.Layout.selectMenuByUrl();
			}
			return;
		}
		$("#ccay_fullscreen_overlay").hide();//解决全屏导出后，点击跳转，遮罩未关闭问题
		Ccay.UI.loading();
		$("#ccayContentPanel").css("visibility", "hidden");
		//var panel = Ccay.Page.getContentPanel();
		
		// 页面跳转前，清理资源
		Ccay.Module.clear();
		Ccay.Page.clearCache();
		// 去除全屏时设置的隐藏滚动条的样式
		$(document.documentElement).removeClass("hidden-scroll");
		$(".ccay-tip.global").remove();
		$("#ccay_float_bar").remove();
		Ccay.Page._beforeForward && Ccay.Page._beforeForward();
		panel.removeAttr('module').ccayLoad(url, function() {
					Ccay.Page.afterForward && Ccay.Page.afterForward();
					Ccay.Page._afterForward && Ccay.Page._afterForward();
					Ccay.Layout.selectMenuByUrl();
				});
//		Ccay.SsoUpdate.request();
		
		//如果用户通过点击菜单访问节点，调用下面方法，高亮显示一级菜单，生成Nav导航条，适用于菜单居顶显示
		if(Ccay.UI.TopMenu != null){
			Ccay.UI.TopMenu.helper.endEvents("#!"+url);
		}
		if(Ccay.UI.TopItem && $("#first_nav").length){
			Ccay.UI.TopItem.helper.selectMenuByUrl();
		}
	},
	/**
	 * 跳转到默认首页方法
	 */
	goHome : function() {
		Ccay.Page.getContentPanel().ccayLoad(Ccay.Page.homePath,
				Ccay.Page.afterForward);
	},

	clearCache : function() {
		this._clearCache && Ccay.Cache.clear();
		this._clearCache = true;
		$.validator.clearTempMethods();
	},
	
	forwardParam:{
 			/**
 			 * 跳转的参数
 			 */
 			url:"",
 			data:"",
			clearCache:"",
	 		/** 是否点解当前节点 */
	 		isSelf:false,
	 		/** 是否在延迟中 */
	 		isDelay:false,
	 		/** 上次跳转的时间 */
	 		lastTime:false,
	 		/** 延迟的方法名 */
	 		interval:""
	},
	/**
	 * @description ajax load方式载入页面资源，模拟跳转。如果url为空，则清空当前面板内容。
	 *              如果带有data参数，则将data的参数序列化后拼接在url后。
	 * @param {String}
	 *            url
	 * @param {Object}
	 *            data
	 * @param {boolean}
	 *            clearCache 不传递默认清空缓存
	 */
	forward : function(url, data, clearCache) {
		//定义跳转的参数
		var forwardParams = Ccay.Page.forwardParam;
		//将每次传过来的跳转的参数保存到全局变量中
		forwardParams.isDelay = true;
			//是否为点击当前页面的节点
		forwardParams.isSelf = (url==window.location.hash) ? true : false;
		forwardParams.url = url;
		forwardParams.data = data;
		forwardParams.clearCache = clearCache;
		//如果setInterval存在就无需再新建，如果第一次访问，就新建一个
		if(forwardParams.interval){
			return;
		}
		//如果上一次跳转距离这一次已经有一段时间间隔了,就无需延迟了,from
		var date = new Date();
		if(date-forwardParams.lastTime>Ccay.Config.Forward.lastTimeSpace){
			forwardParams.isDelay = false;
			Ccay.Page.forwardIntervalMethod();
			return;
		}
		//to
		//开启页面延迟加载的定时器
		forwardParams.interval = setInterval(Ccay.Page.forwardIntervalMethod,Ccay.Config.Forward.delayTime/2);
		//当用户开始点击某一个节点，无论跳转与否都先显示出loading
		Ccay.UI.loading();
	},
	/**
	 * @description 跳转调用的方法
	 */
	forwardIntervalMethod : function(){
		//
		var forwardParams = Ccay.Page.forwardParam;
		//isDelay的总用，每次访问都会将isDelay设置为true，经过这个定时器变为false，不继续执行定时器内其它方法，如果没有再点击其它的节点，false便可以执行以下方法。
		if (forwardParams.isDelay) {
			forwardParams.isDelay = false;
			return;
		}
		var forwardURL = forwardParams.url;
		forwardParams.lastTime = new Date().getTime();
		if(forwardParams.isSelf){
			if(Ccay.Page.ajaxCompleted){//当前ajax请求已完成
				Ccay.Page._forward(forwardURL.indexOf("#!")==0 ? forwardURL.substr(2) :  forwardURL );
			}
		}else{
			Ccay.Page.forwardMethod(forwardURL, forwardParams.data, forwardParams.clearCache);
		}
		//跳转完成，清除定时器
		clearInterval(forwardParams.interval);
		forwardParams.interval=false;
	},
	/**
	 * @description 跳转调用的方法
	 */
	forwardMethod : function(url, data, clearCache){
		if (Ccay.Page.beforeForward
				&& (Ccay.Page.beforeForward(url, data, clearCache) == false)) {
			return;
		}
		if (typeof(url) == "string" && url.indexOf("#!")) {
			url = url.split("#!").pop();
		}
		var realUrl = ['#!'];
		if (!Ccay.DataHelper.isEmpty(url)) {
			realUrl.push(Ccay.Page.register(url));
			if (typeof(data) == "object") {
				if (realUrl.join("").indexOf("?") < 0) {
					realUrl.push("?");
				}
				realUrl.push(Ccay.Core._ajax.serialize(data));
			}
		}
		
		url = realUrl.join("");
		if (clearCache === false)
			this._clearCache = false;
		if (window.location.hash == url)
			Ccay.Page._forward(window.location.hash.substring(2));
		else
			window.location.hash = url;
	},
	/**
	 * @description 刷新当前整个页面
	 */
	refresh : function() {
		location.reload();
	},
	/**
	 * 重新加载内容页面
	 */
	reload : function() {
		Ccay.Page._forward(window.location.hash.substring(2));
	},
	/**
	 * @description 传递一个相对路径，得到一个用于ccay 跳转模式的全路径，带有#！，并就参数序列化在url后。
	 * @param url
	 *            {String} 资源key值或实际路径
	 * @param paras
	 *            {Object} 参数对象
	 */
	getForwardUrl : function(url, paras) {
		var tempUrl = window.location.href.split("#")[0];
		tempUrl += "#!" + url;
		if (typeof(paras) == "object") {
			for (para in paras) {
				tempUrl += para + "=" + paras[para].encodeURI() + "&";
			}
		}
		return tempUrl;
	},
	/**
	 * @description 分析地址栏，并得到参数集合对象
	 * @return args {Object}, 访问某一个参数如 var args=Ccay.Page.getRequest; args.name
	 *         或 args["name"]
	 */
	getRequest : function() {
		var args = new Object();
		var fullUrl = window.location.href;
		var pos1 = fullUrl.search("#");
		if (pos1 < 0)
			return {};
		var tempUrl = fullUrl.substr(pos1 + 1).split("?");
		if (tempUrl.length > 1) {
			var pairs = tempUrl[1].split("&");
			for (var i = 0; i < pairs.length; i++) {
				var pos = pairs[i].indexOf('=');
				if (pos == -1)
					continue;
				var argname = pairs[i].substring(0, pos);
				var value = pairs[i].substring(pos + 1);
				value = decodeURIComponent(value);
				args[argname] = value;
			}
		}
		return args;
	},
	/**
	 * @description load成功后执行方法，用于渲染load的页面，并初始化新加载的模块
	 * @param {JQDom}
	 *            context 需要载入的位置，类型为jquery dom object
	 */
	afterLoad : function(context) {
		Ccay.ready(context);
		Ccay.Module.executeReady();
		$("#ccayContentPanel").css("visibility", "inherit");
		//animate test by zhanghu
//		var panel = $("#ccayMainPanel").addClass("fadeInLeftBig");
//		setTimeout(function(){
//			panel.removeClass("fadeInLeftBig");
//		},3000);
	},
	/**
	 * 返回上一个页面
	 */
	back : function() {
		history.go(-1);
	},
	/**
	 * 显示左边菜单
	 */
	showMenu : function() {
		$("#leftPanel").show();
		$("#midPanel").show();
	},
	/**
	 * 隐藏左菜单
	 */
	hideMenu : function() {
		$("#leftPanel").hide();
		$("#midPanel").hide();
	},
	/**
	 * 显示最大化/恢复按钮
	 */
	showResize : function() {
		$("#resizeWorkSpace").show();
	},
	/**
	 * 隐藏最大化/恢复按钮
	 */
	hideResize : function() {
		$("#resizeWorkSpace").hide();
	},
	/**
	 * 显示页面主体布局
	 * 
	 * @param {}
	 *            boo 不传默认为真， true：只显示页面主体内容布局，false，显示完整页面布局
	 *            showPageNav  最大化时是否显示导航区，默认兼容老版本隐藏
	 *            showSwitchRole 最大化时是否显示角色切换区，默认兼容老版本隐藏
	 */
	showMainOnly : function(boo, showPageNav, showSwitchRole) {
		if (boo === false) {
			$("#head_div").show();
			$("#foot_div").show();
			$("#leftPanel").show();
			$("#midPanel").show();
			$("#ccay_page_nav").show();
			$("#s_switch_role").show();
		} else {
			$("#head_div").hide();
			$("#foot_div").hide();
			$("#leftPanel").hide();
			$("#midPanel").hide();
			(!showPageNav)&&($("#ccay_page_nav").hide());
			(!showSwitchRole)&&($("#s_switch_role").hide());
		}

	},
	/**
	 * 显示页头
	 */
	showHead : function() {
		$("#head_div").show();
	},
	/**
	 * 隐藏页头
	 */
	hideHead : function() {
		$("#head_div").hide();
	},
	/**
	 * 显示页尾
	 */
	showFoot : function() {
		$("#foot_div").show();
	},
	/**
	 * 隐藏页尾
	 */
	hideFoot : function() {
		$("#foot_div").hide();
	},
	/**
	 * 显示面包屑导航
	 */
	showNav : function() {
		$("#ccay_page_nav").show();
	},
	/**
	 * 隐藏面包屑导航
	 */
	hideNav : function() {
		$("#ccay_page_nav").hide();
	},
	/**
	 * 显示角色切换
	 */
	showRoleSwicth : function() {
		$("#s_switch_role").show();
	},
	/**
	 * 隐藏角色切换
	 */
	hideRoleSwicth : function() {
		$("#s_switch_role").hide();
	},
	/**
	 * 根据页面加载样式
	 * @param {} page
	 */
	loadPageCss:function(page){
		var links = page.find("link");
		links.each(function(){
			var link = document.createElement("link");
			link.setAttribute("href",$(this).attr("href"));
			link.setAttribute("rel","stylesheet");
			link.setAttribute("type","text/css");
			page.get(0).appendChild(link);
		});
	}
};

/** ----------------------------- Ccay.Local -------------------------------- */
Ccay.Local = {
	/**
	 * @description 得到当前语言环境，从cookie中读取，如果读取不到，则默认为英文环境
	 * @param {boolean}
	 *            simpleFormat 如果传递了该参数，并且该参数为true，则返回简单语言模式如 cn 、en
	 */
	getCurrLanguage : function(simpleFormat) {
		var strLang = workspaceVO.currentLanguage;
		if (simpleFormat) {
			return strLang.substr(0, 2);
		} else {
			return strLang;
		}
	},
	/**
	 * @description 改变cookie记录的语言环境
	 * @param {string}
	 *            langstr 改变到的语种 zh_CN 或 en_US 等等
	 */
	changeLanguage : function(langstr) {
		$(window.document.body).loading();
		var setting = {
			common : {
				lang : langstr,
				theme: Ccay.Personalized.global.common.theme
			}
		};
		if (Ccay.Personalized && Ccay.Config.Personalized.open) {
			Ccay.Personalized.save(setting, true, function() {
						window.location = Ccay.Config.Service.languageUrl
								.formatURI(window.location.href, langstr);
					})
		} else {
			window.location = Ccay.Config.Service.languageUrl.formatURI(
					window.location.href, langstr);
		}
	}
}
/** ----------------------------- Ccay.ready -------------------------------- */
/**
 * @descriptoion 该方法主要用来配合Ccay.load ,注册并在Ccay.load子页面后，渲染子页面的事件， 用来注册事件，
 *               这些事件会在页面加载完成时候执行。调用方式一： Ccay.ready(function,name) 添加事件 方式二：
 *               Ccay.ready(elementId) 渲染该元素的子节点，不传，则渲染整个页面
 * @param {function}
 *            fn 需要在load页面后执行的函数
 * @param {String}
 *            name 用于log日志输出
 */
Ccay.ready = function(fn, name) {

	if ($.isFunction(fn)) {
		Ccay.ready._list.push(fn);
		Ccay.Core.log("Ccay.ready :注册渲染事件:" + name);
	} else {
		$.each(Ccay.ready._list, function(index, readyFunc) {
					readyFunc(fn);
				});
	}

};
Ccay.ready._list = new Array(); // 页面渲染（初始化）执行方法集合。

/**
 * * ------------------------------------Ccay.Core._ajax*
 * ----------------------------
 */
/** ----------------------------- Ccay 事件代理 -------------------------------- */
Ccay.Core._Delegates = {
	ajax_before : $.Callbacks(),
	ajax_Sucess : $.Callbacks(),
	ajax_Error : $.Callbacks()
};
Ccay.Core._activeForm;// 提交的表单

var _activeForm;

Ccay.Core.setActiveForm = function(activeForm){
	_activeForm = activeForm;
}
Ccay.Core.getActiveForm=function(){
	return _activeForm;
}
Ccay.autoLoading = true;// 系统控制loading开关
/**
 * @description rest数据交互的 ajax函数
 * @param {String}
 *            type rest数据提交类型 分为 GET POST DELETE PUT 四种
 * @param {String}
 *            url service 服务路径
 * @param {Object}
 *            data 参数，可为空
 * @param {funciton}
 *            sucessCallback 请求成功方法
 * @param {funciton}
 *            failCallback 请求失败方法
 * @param {funciton}
 *            fnBeforSend 在Ajax请求执行方法，传入XMLHttpRequest对象参数
 */
Ccay.Core._ajax = function(type, url, data, sucessCallback, failCallback,
		fnBeforSend, autoLoading) {
	var op, ui;
	if ($.isPlainObject(url)) {
		op = url;
		op.type = type;
		ui = data;
	} else {
		op = {
			type : type,
			url : url,
			data : data,
			success : sucessCallback,
			error : failCallback,
			beforeSend : fnBeforSend,
			loading : autoLoading
		}
	}
	Ccay.Core.ajax(op, ui);
};
/**
 * @description 完全自定义ajax请求
 * @param {options}
 *            type rest数据提交类型 分为 GET POST DELETE PUT 四种
 */
Ccay.Core_ajaxCount={"other":0,"get":0};
Ccay.Core.ajax = function(ops, ui) {
	!ui && ops.ui && (ui=ops.ui);
	var op = $.extend(true, {
				contentType : "application/json",
				dataType : "json"
			}, ops);

	if (!op.setAjax || op.setAjax(op, ui) !== false) {
		if (op.getData)
			op.getData(op.success);
		else {
			var fnFilter = op.filter;

			Ccay.autoLoading = op.loading;

			var type = op.type, fnSucess = op.success, fnError = op.error;

			if (type == 'POST' || type == 'PUT') {
				//activeForm = Ccay.Core._activeForm;
				op.data = Ccay.DataHelper.toJsonStr(op.data);
			} else {// GET 时不序列化为JSON字符串
				var query = Ccay.Core._ajax.serialize(op.data);
				if (query)
					op.url += (op.url.indexOf("?") > 0 ? "&" : "?") + query;

				op.data = "";
			}

			//记录当前ajax 的请求数
			var ajaxType =  type !== "GET" ? "other" : "get";
			if( op.loading !== false && !ui){
				Ccay.Core_ajaxCount[ajaxType] ++;
			}
			
			op.success = function(result) {
				//执行成功后，减去1
				if( op.loading !== false && !ui){
					Ccay.Core_ajaxCount[ajaxType] --;
				}
				if (fnFilter)
					result = fnFilter(result);

				if (fnSucess){
					if(Ccay.Config.Global.catchErr){
						try{
							fnSucess.call(this,result);
						}catch(e){
							Ccay.Core.log(e && e.message);
						}
					}else{
						fnSucess.call(this,result);
					}
				}else
					Ccay.UI.topBox({"content":"ccay.common.message.success","style":"success"});

				Ccay.Core._Delegates.ajax_Sucess.fire(type, ui,op);
				Ccay.Core.setActiveForm("");
			};
			op.error = function(xhr, textStatus, errorThrown) {
				//执行成功后，减去1
				if( op.loading !== false && !ui){
					Ccay.Core_ajaxCount[ajaxType] --;
				}
				Ccay.Core._Delegates.ajax_Error.fire(type, ui,op);
				var fnErrorRet;
				if(fnError){
					if(Ccay.Config.Global.catchErr){
						try{
							fnErrorRet = fnError.call(this,textStatus, errorThrown, xhr.responseText,xhr.status);
						}catch(e){
							Ccay.Core.log(e && e.message);
						}
					}else{
						fnErrorRet = fnError.call(this,textStatus, errorThrown, xhr.responseText,xhr.status)
					}
				
				}
				
				if (fnErrorRet) {
					// 如果自定义程序能很好的处理错误
					Ccay.UI.loadingClose();
					Ccay.Core.log("Error handled by errorCallback:"
							+ xhr.responseText);

					return;
				}
				//如果session失效之后,重新执行请求
				Ccay.Core.handleError(xhr.responseText, textStatus, xhr,function(){
					if(xhr.status == 403){
						Ccay.Core._Delegates.ajax_before.fire(op, ui,op);
						$.ajax(op);
					}
				});
				Ccay.Core.setActiveForm("");
				
			};
			Ccay.Core._Delegates.ajax_before.fire(op, ui,op);
//			Ccay.SsoUpdate.request();
			$.ajax(op);
		}
	}
}

//Ccay.Core.handleError = function(responseText, textStatus, xhr, activeForm) {
//	alert(responseText);
//}

/**
 * @description 将对象序列化成用于拼接成url参数形式的字符串
 * @param {Object}
 *            data 需要被序列化的对象
 * @return {String} strParam
 */
Ccay.Core._ajax.serialize = function(data) {
	var strParam = new Array();
	if (typeof(data) !== "object") {
		return data;
	}

	function genQueryParam(data, path) {
		if ($.isArray(data)) {
			for (var i = 0; i < data.length; i++) {
				if (typeof(data[i]) === "object")
					genQueryParam(data[i], path);
				else if (typeof(data[i]) === "string")
					strParam.push(path + "="+ data[i].encodeURI());
				else
					strParam.push(path + "=" + data[i]);
			}
		} else {
			for (var attr in data) {
				var attrValue = data[attr];
				var attrPath = path ? path + "." + attr : attr;
				if (attrValue && attrValue.getTimezoneOffset) {
					strParam.push(attrPath + ".time=" + (attrValue.getTime() - 8 * 60 * 60 * 1000 - attrValue.getTimezoneOffset() * 60 * 1000));
				} else if (typeof(attrValue) === "object") {
					genQueryParam(attrValue, attrPath);
				} else if (typeof(attrValue) === "string") {
					strParam.push(attrPath + "=" + data[attr].encodeURI());
				} else
					strParam.push(attrPath + "=" + data[attr]);
			}
		}
	}
	genQueryParam(data, "");
	strParam = strParam.join("&");
	return strParam;
}
/**
 * 保持Sso session 与cookie请求
 * 
 * @type
 */
//Ccay.SsoUpdate = {
//	ready : false,
//	request : function() {
//		if (!Ccay.SsoUpdate.ready) {
//			Ccay.SsoUpdate.ready = true;
//			setTimeout(function() {
//				Ccay.Core.ajax({
//							url : "only4ssoTimeUpdate.do",
//							sysauto : true,
//							loading : false,
//							success : $.noop
//						});
//				Ccay.SsoUpdate.ready = false;
//				Ccay.Core
//						.log("---------Requst SSO only4ssoTimeUpdate.do---------------");
//			}, 150000);
//		}
//	}
//};
/** -----------------------------------Ccay.Permission------------------------- */
Ccay.Permission = {
	user : workspaceVO.user,
	perms : null,
	res : null
};
/**
 * @description 角色切换
 * @param {String}
 *            target 切换的目标，角色名称
 */
Ccay.Permission.changeRole = function(target) {
	if (Ccay.Permission.beforeChangeRole(target) !== false) {
		$(window.document.body).loading();
		window.location.href = Ccay.Config.Service.changeRole.formatURI(window.location.href,target) + "&t=" + new Date().getTime() + $.newGuid("",5);
	}
};

/**
 * @description 角色切换前执行的事件
 * @param {String}
 *            target 切换的目标，角色名称
 */
Ccay.Permission.beforeChangeRole = function(target) {
};

/**
 * @description 初始化用户对象，将用户的权限与无权限访问的url转换成map
 * @param {object}
 *        user
 */
Ccay.Permission.init = function() {
	//debugger;
	if(!this.user){
		return ;
	}
	var permissions = workspaceVO.permissions;
	this.perms = new Ccay.HashMap()
	this.res = new Ccay.HashMap();
	if (permissions) {
		for (var i = 0; i < permissions.length; i++) {
			this.perms.put(permissions[i], true);
		}
	}
};

/**
 * @description 根据权限表达式，检查当前用户是否包含某单个或多个权限，如果有返回true，否则返回false
 * @param expression
 *            权限表达式，支持 逻辑与 “,” 逻辑或 “|”，但表达式同时只能使用一种逻辑。
 * @param model
 *            模式，有hasPermission 与 noPermisson两种，不传默认为hasPermission
 */
Ccay.Permission.check = function(expression, model) {
	model = model || Ccay.UI.Config.Permission.Model.has;
	if (expression.indexOf("|") >= 0 && expression.indexOf(",") >= 0) {
		Ccay.Core.log("permission 权限点标注错误，不能同时使用逻辑与“|”与逻辑或“,”来控制元素显示:"
						+ expression, Ccay.Config.Log.error);
		return false;
	}
	if (expression.indexOf("|") >= 0) {
		return Ccay.Permission._checkAnyOne(expression.split("|"), model)
	} else if (expression.indexOf(",") >= 0) {
		return Ccay.Permission._checkAll(expression.split(","), model)
	} else {
		return Ccay.Permission._check(expression, model);
	}
}

/**
 * @decription model为hasPermission时候，检查用户是否包含某单个权限,
 *             model为noPermission时候检查用户是否没有某单个权限
 * @param {Object}
 *            permissions
 * @param {String}
 *            model 两种模式，1 hasPermission 2 noPermission
 * @return {boolean}
 */
Ccay.Permission._check = function(permission, model) {
	if(!this.perms){
		return false;
	}
	if (model == "hasPermission")
		return this.perms.get($.trim(permission)) ? true : false;
	else
		return this.perms.get($.trim(permission)) ? false : true;
}

/**
 * @decription model为hasPermission时候，检查用户是否包含参数提供的所有权限,
 *             model为noPermission时候检查用户是否没有权限表达式中的任意一个权限
 * @param permissions
 *            {Array}
 * @param model
 *            {String} 两种模式，1 hasPermission 2 noPermission
 * @return boo {boolean}
 */
Ccay.Permission._checkAll = function(permissions, model) {
	if(!this.perms){
		return false;
	}
	for (var i = 0; i < permissions.length; i++) {
		if (model == "hasPermission") {
			if (!this.perms.get($.trim(permissions[i]))) {
				return false;
			}
		} else {
			if (this.perms.get($.trim(permissions[i]))) {
				return false;
			}
		}
	}
	return true;
}

/**
 * @decription model为hasPermission时候，检查用户是否包其中某一个权限,
 *             model为noPermission时候检查用户是否没有其中任意一个权限
 * @param permissions
 *            {Array}
 * @param model
 *            {String} 两种模式，1 hasPermission 2 noPermission
 * @return boo {boolean}
 */
Ccay.Permission._checkAnyOne = function(permissions, model) {
	if(!this.perms){
		return false;
	}
	for (var i = 0; i < permissions.length; i++) {
		if (model == "hasPermission") {
			if (this.perms.get($.trim(permissions[i]))) {
				return true;
			}
		} else {
			if (!this.perms.get($.trim(permissions[i]))) {
				return true;
			}
		}
	}
	return false;
};

/** -----------------------------------Ccay.Cache------------------------- */

Ccay.Cache = {
	// 缓存对象
	_cacheMap : {},
	/**
	 * 根据key值拿到缓存数据，如果找不到缓存，则返回undefined
	 * 
	 * @param {}
	 *            key
	 * @return {objct} data;
	 */
	get : function(key) {
		return this._cacheMap[key];
	},
	/**
	 * 添加缓存数据
	 * 
	 * @param {String}
	 *            key
	 * @param {Object}
	 *            data
	 */
	put : function(key, data) {
		this._cacheMap[key] = data;
	},
	// 清除所有缓存
	clear : function() {
		this._cacheMap = {};
	},
	// 根据key值移除缓存
	remove : function(key) {
		try {
			delete this._cacheMap[key];
		} catch (e) {
		}
	}
};

// 处理键盘事件 禁止后退键（Backspace）密码或单行、多行文本框除外
Ccay.Core.forbidBackSpace = function(e) {
	var ev = e || window.event; // 获取event对象
	if (ev.keyCode == 8) {
		var obj = ev.target || ev.srcElement; // 获取事件源
		// if($(obj).attr("ingrid") && $.browser.msie &&
		// Ccay.UI.getInputFocus(obj)==0){
		// _stopDefasultEvent(e);
		// return false;
		// }
		var t = obj.type || obj.getAttribute('type'); // 获取事件源类型
		// 获取作为判断条件的事件类型
		var vReadOnly = obj.readOnly;
		var vDisabled = obj.disabled;
		// 处理undefined值情况
		vReadOnly = (vReadOnly == undefined) ? false : vReadOnly;
		vDisabled = (vDisabled == undefined) ? true : vDisabled;
		// 当敲Backspace键时，事件源类型为密码或单行、多行文本的，
		// 并且readOnly属性为true或disabled属性为true的，则退格键失效
		var flag1 = (t == "password" || t == "text" || t == "textarea")
				&& (vReadOnly == true || vDisabled == true);
		// 当敲Backspace键时，事件源类型非密码或单行、多行文本的，则退格键失效
		var flag2 = t != "password" && t != "text" && t != "textarea";
		// 判断
		if (flag2 || flag1) {
			_stopDefasultEvent(e);
			return false;
		}
	}
};

/**
 * hwa统一接口
 * opr_wf_n {String} 操作名称 ，最好你们传业务值入来，这个值是固定的
 * opr_wf_d {Number} 操作耗时
 * url {String} 页面地址
 * opts Object 参数{opr_wf_n、opr_wf_d}
 */
//Ccay.Hwa = {
//	send : function(opr_wf_n, opr_wf_d, url, opts){
//		if(workspaceVO.config.hwa=="0"){
//			return;
//		}
//		if(typeof opr_wf_n == "object"){
//			opts = opr_wf_n;
//		}else{
//			opts = opts || {};
//			opr_wf_n && (opts.opr_wf_n = opr_wf_n);
//			opr_wf_d && (opts.opr_wf_d = opr_wf_d);
//			url && (opts.url = url);
//		}
//		ha("trackEvent","click",opts);
//	}
//};
